/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2013-11-30         luwei
 */

package com.coocaa.x.app.hall.parser.layoutparser;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.util.SparseArray;
import android.view.View;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.LayoutAnimationController;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;

import com.coocaa.x.app.hall.parser.ActionParser;
import com.coocaa.x.app.hall.parser.ActionParser.ParseIntent;
import com.coocaa.x.app.hall.parser.ParserData;
import com.coocaa.x.app.hall.parser.ViewParser;
import com.coocaa.x.app.hall.view.HallItemView;
import com.coocaa.x.app.hall.view.ReflectionView;
import com.coocaa.x.framework.app.CoocaaApplication;
import com.coocaa.x.framework.utils.LogUtils;
import com.coocaa.x.uipackage.BaseView;
import com.coocaa.x.uipackage.widget.SlideFocusView;
import com.coocaa.x.uipackage.widget.SlideFocusView.FocusChangedEvent;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class BaseCustomLayout extends RelativeLayout implements ViewParser.IViewLoadOverListener {
    private static final String tag = "BaseCustomLayout";
    private SparseArray<Integer> mBlockMap = new SparseArray<Integer>();
    private SparseArray<Integer> mFocusViewPos = new SparseArray<Integer>();
    private List<BlockData> mBlockNum = new ArrayList<BlockData>();
    private int mRow = 3;
    private int mCol = 4;
    private int mVerticalSpace = 30;
    private int mHorizontalSpace = 30;
    private int mBlockWidth = 200;
    private int mBlockHeight = 200;
    private int mMarginLeft = 0;
    private int mMarginTop = 0;
    private int mMarginRight = 0;
    private int mMarginBottom = 0;
    private int mBlockShadowX = 0;
    private int mBlockShdowY = 0;
    private int mMaxBlockValue = 0;
    private static final int INIT_ID = 0x0fff0100;
    private int mInitId = INIT_ID;
    private int mReflectionId = INIT_ID;
    private List<View> mChildViews = new ArrayList<View>();
    private Context mContext = null;
    HashMap<Integer, Integer> lineMap = new HashMap<Integer, Integer>();
    private FocusChangedEvent mFocusChangedEvent = null;
    protected OnKeyListener mOnItemKeyEventListener = null;
    protected OnFocusChangeListener mOnItemFocusChangeListener = null;
    protected IItemViewLoadOverListener itemViewLoadOverListener = null;
    protected OnClickListener mOnItemClickListener = null;
    protected SlideFocusView.FocusViewRevision mFocusViewRevision;
    protected HashMap<Integer, String> appItemNumMap = null;
    protected HashMap<String, List<View>> appItemViewMap = null;
    protected HashMap<View, ReflectionView> reflectionMap = new HashMap<View, ReflectionView>();
    protected List<Integer> bottomList = new ArrayList<Integer>();
    protected ViewParser mViewParser = null;

    public interface IItemViewLoadOverListener {
        public void viewLoadOver(HashMap<Integer, String> appItemNumMap);
    }

    public BaseCustomLayout(Context context) {
        super(context);
        this.mContext = context;
        mInitId = INIT_ID;
        mViewParser = new ViewParser(mContext);
        mViewParser.setIViewLoadOverListener(this);
        appItemNumMap = new HashMap<Integer, String>();
        appItemViewMap = new HashMap<String, List<View>>();
        mFocusViewRevision = new SlideFocusView.FocusViewRevision(CoocaaApplication.Div(108), CoocaaApplication.Div(108));
    }

    public class BlockSize {
        private int blockWith = 1;
        private int blockHeight = 1;

        public int getBlockWith() {
            return blockWith;
        }

        public void setBlockWith(int blockWith) {
            this.blockWith = blockWith;
        }

        public int getBlockHeight() {
            return blockHeight;
        }

        public void setBlockHeight(int blockHeight) {
            this.blockHeight = blockHeight;
        }

    }

    public static class BlockData {
        public int mRowNum = 0;
        public int mColNum = 0;
        public int mMarginLeft = 0;
        public int mMarginRight = 0;
        public int mMarginBottom = 0;
        public int mMarginTop = 0;
        public int mWidth = 0;
        public int mHeight = 0;
        public int[] mBlock = null;
        public boolean[] mTurnPage = null;
    }

    public static class CustomLayoutParams {
        public int mRow = 4;//行
        public int mCol = 1000;//列
        public int mVerticalSpace = 25;
        public int mHorizontalSpace = 25;
        public int mBlockWidth = 295;
        public int mBlockHeight = 295;
        public int mMarginRight = 0;
        public int mMarginBottom = 0;
        public int mMarginLeft = 0;
        public int mMarginTop = 0;
        public int mBlockShadowX = 0;
        public int mBlockShadowY = 0;

    }

    public void setBlockDatas(List<BlockData> nums) {
        this.mBlockNum = nums;
    }

    public void setVerticalSpace(int space) {
        this.mVerticalSpace = space;
    }

    public void setHorizontalSpace(int space) {
        this.mHorizontalSpace = space;
    }

    public void setCustomLayoutParams(CustomLayoutParams params) {
        this.mRow = params.mRow;
        this.mCol = params.mCol;
        this.mVerticalSpace = params.mVerticalSpace;
        this.mHorizontalSpace = params.mHorizontalSpace;
        this.mBlockWidth = params.mBlockWidth;
        this.mBlockHeight = params.mBlockHeight;
        this.mMarginLeft = params.mMarginLeft;
        this.mMarginTop = params.mMarginTop;
        this.mMarginRight = params.mMarginRight;
        this.mMarginBottom = params.mMarginBottom;
        this.mBlockShadowX = params.mBlockShadowX;
        this.mBlockShdowY = params.mBlockShadowY;

        int i;
        for (i = 1; i <= this.mRow; i++) {
            lineMap.put(i, 0);
        }
    }

    public void setMargin(int left, int top, int right, int bottom) {
        this.mMarginLeft = left;
        this.mMarginTop = top;
        this.mMarginRight = right;
        this.mMarginBottom = bottom;
    }

    private int getMaxRow(HashMap<Integer, Integer> map) {
        int maxLine = 1;
        int i;

        for (i = 1; i <= map.size(); i++) {
            if (map.get(i) >= map.get(maxLine)) {
                maxLine = i;
            }
        }

        return maxLine;
    }

    public int getLayoutRowNum() {
        return this.mRow;
    }

    public BlockData getBlockData(int index) {
        if (index >= mBlockNum.size() || index < 0)
            return null;
        return mBlockNum.get(index);
    }

    public void setChildViews(List<View> views) {
        this.mChildViews = views;
        removeAllViews();
    }

    public List<View> getChildViews() {
        return this.mChildViews;
    }

    public void onResume() {
        if (mChildViews != null && mChildViews.size() > 0) {
            for (View view : mChildViews) {
                if (view instanceof HallItemView)
                    ((HallItemView) view).onResume();
            }
        }
    }

    public void onDestroy() {
        mViewParser = null;
        mFocusChangedEvent = null;
        mOnItemKeyEventListener = null;
        mOnItemFocusChangeListener = null;
        itemViewLoadOverListener = null;
        mOnItemClickListener = null;

        this.removeAllViews();

        if (JsonList != null) {
            JsonList.clear();
            JsonList = null;
        }

        if (actionJsonList != null) {
            actionJsonList.clear();
            actionJsonList = null;
        }

        if (mChildViews != null) {
            for (View view : mChildViews) {
                if (view instanceof HallItemView)
                    ((HallItemView) view).onDestroy();
            }

            mChildViews.clear();
            mChildViews = null;
        }

        if (appItemNumMap != null) {
            appItemNumMap.clear();
            appItemNumMap = null;
        }

        if (appItemViewMap != null) {
            appItemViewMap.clear();
            appItemViewMap = null;
        }

        if (lineMap != null) {
            lineMap.clear();
            lineMap = null;
        }

        if (mBlockMap != null) {
            mBlockMap.clear();
            mBlockMap = null;
        }

        if (mBlockNum != null) {
            mBlockNum.clear();
            mBlockNum = null;
        }

        if (mFocusViewPos != null) {
            mFocusViewPos.clear();
            mFocusViewPos = null;
        }

        if (reflectionMap != null) {
            ReflectionView imageView;
            View view;
            for (Map.Entry<View, ReflectionView> entry : reflectionMap.entrySet()) {
                imageView = entry.getValue();
                if (imageView != null) {
                    imageView.onDestroy();
                    view = entry.getKey();
                    if (view != null) {
                        ((BaseView) view).removeView(imageView);
                        view.destroyDrawingCache();
                    }
                }
            }

            reflectionMap.clear();
            reflectionMap = null;
        }


        if (bottomList != null) {
            bottomList.clear();
            bottomList = null;
        }

        this.destroyDrawingCache();
//        System.gc();
    }

    public int getRows() {
        return mRow;
    }

    /**
     * 获取基本block最大列数
     *
     * @return
     */
    public int getMaxCol() {
        return lineMap.get(getMaxRow(lineMap));
    }

    public int getBlockFirstPos(int index) {
        if (index >= mBlockNum.size())
            return -1;
        return mBlockNum.get(index).mBlock[0];
    }

    public int getIndex(int id) {
        return id - INIT_ID;
    }

    public boolean isFirstColBlock(int index) {
        int firstBlock = getBlockFirstPos(index);
        if (0 <= firstBlock && firstBlock <= mRow)
            return true;
        else
            return false;
    }

    /**
     * 判断指定item是否属于最后一列
     *
     * @param index
     * @return
     */
    public boolean isLastColBlock(int index) {
        int lastBlock = getBlockLastPos(index);

        if (lastBlock != -1 && lastBlock / mRow == getMaxCol() - 1) {
            return true;
        }
        return false;
    }

    public int getBlockLastPos(int index) {
        if (mBlockNum.size() <= index)
            return -1;
        int length = mBlockNum.get(index).mBlock.length;
        return mBlockNum.get(index).mBlock[length - 1];
    }

    public int getNextRightIndex(int curIndex) {
        int nextIndex = -1;
        int curRow;
        int nextCol;
        int nextFirstBlock;

        if (curIndex >= mBlockNum.size())
            return -1;
        BlockData curBlockData = mBlockNum.get(curIndex);

        curRow = (curBlockData.mBlock[0]) % mRow;
        nextCol = (curBlockData.mBlock[0]) / mRow + curBlockData.mColNum;
        nextFirstBlock = nextCol * mRow + curRow;

        LogUtils.i(tag, "get next nextFirstBlock " + nextFirstBlock + ", nextCol" + nextCol);

        if (mFocusViewPos.indexOfKey(nextFirstBlock) >= 0) {
            nextIndex = mFocusViewPos.get(nextFirstBlock);
        } else if (nextCol * mRow <= mMaxBlockValue
                && mFocusViewPos.indexOfKey(nextCol * mRow) >= 0) {
            nextIndex = mFocusViewPos.get(nextCol * mRow);
        }

        return nextIndex;
    }

    public int getNextLeftIndex(int curIndex) {
        int nextIndex = -1;
        int curRow;
        int nextCol;
        int nextFirstBlock;

        if (curIndex >= mBlockNum.size())
            return -1;
        BlockData curBlockData = mBlockNum.get(curIndex);

        curRow = (curBlockData.mBlock[0]) % mRow;
        nextCol = (curBlockData.mBlock[0]) / mRow - 1;
        nextFirstBlock = nextCol * mRow + curRow;
        if (nextFirstBlock >= 0 && mFocusViewPos.indexOfKey(nextFirstBlock) >= 0) {
            nextIndex = mFocusViewPos.get(nextFirstBlock);
        }

        return nextIndex;
    }

    public int getNextDownIndex(int index) {
        int nextIndex = -1;
        int maxRow;
        int nextFirstBlock;
        if (index >= mBlockNum.size())
            return -1;
        BlockData curBlockData = mBlockNum.get(index);
        maxRow = (curBlockData.mBlock[0] + curBlockData.mRowNum - 1) % mRow;

        nextFirstBlock = curBlockData.mBlock[0] + curBlockData.mRowNum;
        if (maxRow < mRow - 1 && nextFirstBlock < mFocusViewPos.size()) {
            if (mFocusViewPos.indexOfKey(nextFirstBlock) >= 0) {
                nextIndex = mFocusViewPos.get(nextFirstBlock);
            }
        }
        return nextIndex;
    }

    public int getNextUpIndex(int index) {
        int nextIndex = -1;
        int firstRow;
        if (index >= mBlockNum.size())
            return -1;
        BlockData curBlockData = mBlockNum.get(index);
        firstRow = curBlockData.mBlock[0] % mRow;

        if (firstRow > 0) {
            if (mFocusViewPos.indexOfKey(curBlockData.mBlock[0] - 1) >= 0)
                nextIndex = mFocusViewPos.get(curBlockData.mBlock[0] - 1);
        }
        return nextIndex;
    }

    public int getBlockViewPos(int index) {
        try {
            return mFocusViewPos.get(index);
        } catch (Exception e) {
            return -1;
        }
    }

//    public int getAppItemNum(String pkg)
//    {
//        if(appItemNumMap.containsKey(pkg))
//            return appItemNumMap.get(pkg);
//        else
//            return 0;
//    }

    public HashMap<Integer, String> getItemNumMap() {
        return appItemNumMap;
    }

    public List<View> getAppViewList(String pkg) {
        if (appItemViewMap.containsKey(pkg))
            return appItemViewMap.get(pkg);
        else
            return null;
    }

    public ParseIntent getItemIntent(int id) throws PackageManager.NameNotFoundException {
        int index = getIndex(id);

        if (actionJsonList == null || actionJsonList.size() < index)
            return null;

        ActionParser parser = new ActionParser();
        ParseIntent intent = parser.parse(actionJsonList.get(index));
        return intent;
    }

    public boolean isNoItem() {
        if (mChildViews == null || mChildViews.size() == 0)
            return true;
        return false;
    }

    private String getPackageName(String actionJson) {
        String pkgName = null;
        ParseIntent intent;
        try {
            ActionParser parser = new ActionParser();
            intent = parser.parse(actionJson);
            if(intent != null)
                pkgName = intent.pkgName;
        } catch (PackageManager.NameNotFoundException e) {
            pkgName = e.getMessage();
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return pkgName;
    }

    public int getBlockViewWidth(int pos) {
        int width;
        if (pos >= mBlockNum.size())
            return -1;
        BlockData curBlockData = mBlockNum.get(pos);
        width = curBlockData.mColNum * (this.mBlockWidth + this.mHorizontalSpace);
        return width;
    }

    public void setBlockSize(int width, int height) {
        this.mBlockWidth = width;
        this.mBlockHeight = height;
    }

    public void setBlockNum(int row, int col) {
        this.mRow = row;
        this.mCol = col;
    }

    public void setOnItemKeyEventListener(
            OnKeyListener mOnItemKeyEventListener) {
        this.mOnItemKeyEventListener = mOnItemKeyEventListener;
    }

    public void setIItemViewLoadOverListener(
            IItemViewLoadOverListener listener) {
        this.itemViewLoadOverListener = listener;
    }

    public void setOnItemFocusChangeListener(
            OnFocusChangeListener listener) {
        this.mOnItemFocusChangeListener = listener;
    }

    public void setOnItemClickListener(OnClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    public void setAnimation(int id) {
        AnimationSet set = new AnimationSet(true);
        set.addAnimation(AnimationUtils.loadAnimation(mContext, id));
        LayoutAnimationController controller = new LayoutAnimationController(set, 0.5f);
        controller.setOrder(LayoutAnimationController.ORDER_NORMAL);
    }

    public void setFocusChangedEvent(FocusChangedEvent focusChangedEvent) {
        this.mFocusChangedEvent = focusChangedEvent;
    }

    String pagerJson;
    List<String> JsonList;
    List<String> actionJsonList;

    public void setJson(String json) {
        pagerJson = json;
        divideLayout();
        //解析jsong
    }

    public void setJson(List<String> jsonList) {
        JsonList = jsonList;
        actionJsonList = new ArrayList<String>();
        divideLayout();
    }

    public BaseView parse(BlockSize mBlockSize, String json) {
        BaseView view;
        BlockData block = generateAppBlockData(mBlockSize);
        if (mViewParser == null) {
            mViewParser = new ViewParser(mContext);
            mViewParser.setIViewLoadOverListener(this);
        }

        if (block.mRowNum >= 2 && block.mColNum >= 2)
            view = mViewParser.parse(json, true);
        else
            view = mViewParser.parse(json, false);

        mBlockNum.add(block);
        if (view != null) {
            int widthParams = block.mWidth;
            if (widthParams == 0) {
                widthParams = block.mColNum * mBlockWidth + (block.mColNum - 1)
                        * mHorizontalSpace;// + 2 * mBlockShadowX;
            } else {
                widthParams = block.mWidth;
            }

            int heightParams = block.mHeight;
            if (heightParams == 0) {
                heightParams = block.mRowNum * mBlockHeight + (block.mRowNum - 1)
                        * mVerticalSpace;// + 2 * mBlockShadowY;
            }
            view.setId(mInitId++);
            LogUtils.d(tag, "the position " + (mInitId - INIT_ID) + " the id is" + view.getId());
            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(widthParams,
                    heightParams);
            if (block.mBlock[0] == 0)//第一个模块
            {
                params.setMargins(block.mMarginLeft + mMarginLeft + CoocaaApplication.Div(148),
                        mVerticalSpace + block.mMarginTop + mMarginTop,// - 2 * mBlockShadowY,
                        block.mMarginRight,
                        block.mMarginBottom);
            } else if (block.mBlock[0] < mRow)//第一列
            {
                params.setMargins(block.mMarginLeft + mMarginLeft + CoocaaApplication.Div(148),
                        mHorizontalSpace + block.mMarginTop,
                        block.mMarginRight,
                        block.mMarginBottom);
            } else if (block.mBlock[0] % mRow == 0)//边界
            {
                //       
                params.setMargins(block.mMarginLeft + mVerticalSpace, mVerticalSpace
                                + block.mMarginTop + mMarginTop,//- 2 * mBlockShadowY,
                        block.mMarginRight, block.mMarginBottom);
            } else {
                //
                params.setMargins(block.mMarginLeft + mVerticalSpace,
                        mHorizontalSpace + block.mMarginTop,
                        block.mMarginRight, block.mMarginBottom);
            }
            if (mBlockMap.size() > 0) {
                if (block.mBlock[0] % mRow != 0) //不是在开始第一列，==0为每一列开始
                {
                    int id = 0;
                    if (mBlockMap.get(block.mBlock[0] - 1) == null) {
                        id = mBlockMap.get(block.mBlock[0] - mRow);
                    } else {//前面有item
                        id = mBlockMap.get(block.mBlock[0] - 1);
                    }
                    params.addRule(RelativeLayout.BELOW, id);
                }
                if (block.mBlock[0] - mRow >= 0) {
                    int id = mBlockMap.get(block.mBlock[0] - mRow);
                    params.addRule(RelativeLayout.RIGHT_OF, id);
                }
            }
            view.setLayoutParams(params);
            for (Integer value : block.mBlock) {
                mBlockMap.put(value, view.getId());
                mFocusViewPos.put(value, (mInitId - INIT_ID) - 1);
                if (value > mMaxBlockValue)
                    mMaxBlockValue = value;

                if (value % mRow == mRow - 1) {
                    if (!bottomList.contains(mFocusViewPos.get(value))) {
                        bottomList.add(mFocusViewPos.get(value));
                    }
                }
            }
        }

        return view;
    }

    private int getMinRow(HashMap<Integer, Integer> map) {
        int minLine = map.size();
        int i;

        for (i = map.size(); i >= 1; i--) {
            if (map.get(i) <= map.get(minLine)) {
                minLine = i;
            }
        }

        return minLine;
    }

    public BlockData generateAppBlockData(BlockSize mBlockSize) {
        if (mBlockSize == null) {
            return null;
        }

        int col;
        int row;
        int minLineNum = getMinRow(lineMap);
        int minLineValue = lineMap.get(minLineNum);

        int maxLineNum = getMaxRow(lineMap);
        int maxLineValue = lineMap.get(maxLineNum);

        int with = mBlockSize.getBlockWith();
        int height = mBlockSize.getBlockHeight();

        BlockData data1 = new BlockData();
        data1.mTurnPage = new boolean[]{false, false, false, false};
        data1.mColNum = with; //列
        data1.mRowNum = height; //行
        data1.mBlock = new int[height * with];

        LogUtils.i(tag, "minLineNum = " + minLineNum + "; minLineValue = " + minLineValue);
        LogUtils.i(tag, "maxLineNum = " + maxLineNum + "; maxLineValue = " + maxLineValue);
        if (maxLineValue == minLineValue) //右边已经对齐
        {
            for (col = 0; col < with; col++) {
                for (row = 0; row < height; row++) {
                    data1.mBlock[row + height * col] = (minLineValue) * this.mRow + col * this.mRow + row;
                }
            }

            for (row = 0; row < height; row++) {
                lineMap.put(row + 1, minLineValue + with);
            }
        } else {
            if ((lineMap.size() >= minLineNum + height - 1) && lineMap.get(minLineNum + height - 1) == minLineValue) //下方还有足够空间
            {
                for (col = 0; col < with; col++) {
                    for (row = 0; row < height; row++) {
                        data1.mBlock[row + height * col] = (minLineValue) * this.mRow + minLineNum - 1 + col * this.mRow + row;
                    }
                }

                for (row = 0; row < height; row++) {
                    lineMap.put(minLineNum + row, minLineValue + with);
                }
            } else//最短行下方没有足够空间，从最大列开始
            {
                for (col = 0; col < with; col++) {
                    for (row = 0; row < height; row++) {
                        data1.mBlock[row + height * col] = (maxLineValue) * this.mRow + col * this.mRow + row;
                    }
                }

                for (row = 0; row < height; row++) {
                    lineMap.put(1 + row, maxLineValue + with);
                }
            }
        }

        return data1;
    }

    private void divideLayout() {
        int count = 0;
        mFocusViewPos.clear();
        BlockSize mBlockSize;
        View lastView = null;
        mReflectionId = INIT_ID + JsonList.size();
        for (String json : JsonList) {
            ParserData.Root_Node action = ParserData.Root_Node.parseJObject(json, ParserData.Root_Node.class);

            String viewJason = action.view;
            String layoutJson = action.layout;

            actionJsonList.add(action.action);

            ParserData.Layout_Node LayoutAction = ParserData.Layout_Node.parseJObject(layoutJson, ParserData.Layout_Node.class);
            String layoutValue;

            if (LayoutAction.getValueName().equals("layout_hall")) ;
            {
                ParserData.Layout_Node.Layout_Hall layout_hall = ParserData.Layout_Node.Layout_Hall.parseJObject(LayoutAction.value, ParserData.Layout_Node.Layout_Hall.class);
                layoutValue = layout_hall.layout;
            }

            mBlockSize = new BlockSize();

            if (layoutValue == null) {
                mBlockSize.setBlockHeight(1);
                mBlockSize.setBlockWith(1);
            } else {
                layoutValue = layoutValue + " ";
                try {
                    mBlockSize.setBlockWith(Integer.valueOf(layoutValue.substring(0, 1)));
                    mBlockSize.setBlockHeight(Integer.valueOf(layoutValue.substring(2, 3)));
                } catch (Exception e) {
                    mBlockSize.setBlockHeight(1);
                    mBlockSize.setBlockWith(1);
                    e.printStackTrace();
                }

            }

            BaseView view = parse(mBlockSize, viewJason);
            mChildViews.add(view);

            view.setOnKeyListener(mOnItemKeyEventListener);
            view.setOnClickListener(mOnItemClickListener);
            if (mFocusChangedEvent != null) {
                mFocusChangedEvent.registerView(view, mFocusViewRevision, mOnItemFocusChangeListener);//(OnFocusChangeListener)view);
            }
            addView(view);

            //底部的view
            if (bottomList.contains(view.getId() - INIT_ID)) {
                LogUtils.i(tag, "reflectionMap add " + (view.getId() - INIT_ID));
                BaseView reflectionView = new BaseView(mContext);
                reflectionView.enableFocusable(false);
                RelativeLayout.LayoutParams viewParams = (RelativeLayout.LayoutParams) view.getLayoutParams();
                RelativeLayout.LayoutParams reflectionParams = new RelativeLayout.LayoutParams(viewParams.width, CoocaaApplication.Div(100));
                reflectionParams.topMargin = CoocaaApplication.Div(15);
                reflectionParams.rightMargin = mHorizontalSpace;

                if (lastView != null) {
                    reflectionParams.addRule(RelativeLayout.RIGHT_OF, lastView.getId());
                } else
                    reflectionParams.leftMargin = CoocaaApplication.Div(148);

                reflectionParams.addRule(RelativeLayout.BELOW, view.getId());

                reflectionView.setId(mReflectionId);
                reflectionView.setLayoutParams(reflectionParams);
                this.addView(reflectionView);
                lastView = reflectionView;
                ReflectionView imageView = new ReflectionView(mContext, viewParams.width, viewParams.height);

                FrameLayout.LayoutParams imageParams = new FrameLayout.LayoutParams
                        (FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
                imageView.setLayoutParams(imageParams);
                reflectionView.addView(imageView);
                reflectionMap.put(view, imageView);
                mReflectionId++;
            }

            if (count == JsonList.size() - 1) {
                BaseView nullView = new BaseView(mContext);
                RelativeLayout.LayoutParams nullViewParams = new RelativeLayout.LayoutParams(CoocaaApplication.Div(100), CoocaaApplication.Div(100));
                nullViewParams.addRule(RelativeLayout.RIGHT_OF, view.getId());
                nullView.setLayoutParams(nullViewParams);
                nullView.enableFocusable(false);
                this.addView(nullView);
            }
            count++;
        }

        getAllItemPackageName();
        hideItems(count);
        requestLayout();
    }

    public int getItemNum() {
        if (mChildViews != null)
            return mChildViews.size();
        return 0;
    }

    public View getItem(int index) {
        if (mChildViews != null && index < mChildViews.size() && index >= 0)
            return mChildViews.get(index);
        return null;
    }

    private void hideItems(int count) {
        if (count < mChildViews.size()) {
            for (int i = count; i < mChildViews.size(); i++) {
                View view = mChildViews.get(i);
                if (view != null) {
                    removeView(view);
                }
            }
        }
    }

    public boolean setFocusPos(int pos, boolean focus) {
        if (pos < mChildViews.size()) {
            View view = mChildViews.get(pos);
            if (view != null) {
                if (focus) {
                    view.requestFocus();
                } else {
                    view.clearFocus();
                }
            }
        } else {
            if (mChildViews.size() > 0) {
                if (focus) {
                    mChildViews.get(mChildViews.size() - 1).requestFocus();
                } else {
                    mChildViews.get(mChildViews.size() - 1).clearFocus();
                }
            } else {
                return false;
            }
        }
        return true;
    }

    public boolean isItemFocus() {
        for (View view : mChildViews) {
            if (view.isFocused()) {
                return true;
            }
        }
        return false;
    }

    private void getAllItemPackageName() {
//        AsyncTask.runOnThread(new Runnable() {
//            @Override
//            public void run() {
//                if(actionJsonList != null && actionJsonList.size() > 0)
//                {
        String pagName = null;
        int i = 0;
        for (String action : actionJsonList) {
            pagName = getPackageName(action);
            View view = mChildViews.get(i);
            if (pagName != null) {
                appItemNumMap.put(view.getId(), pagName);
            }
            i++;
        }

        if (itemViewLoadOverListener != null)
            itemViewLoadOverListener.viewLoadOver(appItemNumMap);
    }
//            }
//        });
//    }

    Handler mHandler = new Handler() {
        @Override
        public void dispatchMessage(Message msg) {
            int id = msg.arg1;
            if(mChildViews == null || mChildViews.size() <= (id - INIT_ID) || (id - INIT_ID) < 0)
                return;
            View view = mChildViews.get(id - INIT_ID);
            ReflectionView imageView = reflectionMap.get(view);
            Bitmap bitmap = (Bitmap) msg.obj;
            if (imageView == null || bitmap == null)
                return;
            imageView.setReflectionBitmap(bitmap);
        }
    };

    @Override
    public void viewImageLoadOver(final View view, final Bitmap bitmap) {

        synchronized (this) {
            if (bottomList.contains(view.getId() - INIT_ID)) {
                LogUtils.i(tag, "view index = " + (view.getId() - INIT_ID));
                Message message = new Message();
                message.arg1 = view.getId();
                message.obj = bitmap;
                mHandler.sendMessage(message);
            }
        }
    }
}
